package tpdisenio2009.mvp.presenter;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import tpdisenio2009.Constants;
import tpdisenio2009.Tpdisenio2009App;
import tpdisenio2009.model.beans.FantasyTeam;
import tpdisenio2009.model.beans.FantasyTeamPlayer;
import tpdisenio2009.model.beans.SoccerPlayer;
import tpdisenio2009.model.beans.User;
import tpdisenio2009.mvp.display.CreateFantasyTeamView;
import tpdisenio2009.mvp.display.QueryAFAPlayersViewImpl;
import tpdisenio2009.services.FantasyTeamService;
import tpdisenio2009.services.RealTeamService;
import tpdisenio2009.services.UserService;

/**
 *
 * @author Nicolás Galliano
 */
public class CreateFantasyTeamPresenter extends DefaultPresenter<CreateFantasyTeamView> {

    private final RealTeamService rtservice;
    private final FantasyTeamService ftservice;
    private final UserService userService;

    private ActionListener queryPlayersListener;
    private ActionListener savePlayersListener;
    private ActionListener exitPlayersListener;

    public CreateFantasyTeamPresenter(CreateFantasyTeamView view) {
        super(view);

        rtservice = new RealTeamService();
        ftservice = new FantasyTeamService();
        userService = new UserService();

        getView().setLLevasGastado( getFantasyTeamCotization() );
        getView().setTeQuedan( Constants.TOTAL_MONEY - getFantasyTeamCotization() );

        bind();
    }

    public int getFantasyTeamCotization() {
        int cotization = 0;

        List<SoccerPlayer> soccerPlayers = getView().getSoccerPlayers();
        for (SoccerPlayer player : soccerPlayers)
            cotization += player.getPrice();

        return cotization;
    }

    public void bind() {
        
        queryPlayersListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String position = null;
                SoccerPlayer soccerPlayer = null;
                int index = getView().getSelectedPosition();

                if (index >= 0) {
                    soccerPlayer = getView().getPlayerAtPosition( index );

                    if (index == 0 || index == 11)
                        position = SoccerPlayer.GOALKEEPER_POSITION;
                    else if (index > 0 && index < 5 || index == 12)
                        position = SoccerPlayer.DEFENDER_POSITION;
                    else if (index > 4 && index < 8 || index == 13)
                        position = SoccerPlayer.MIDFIELDER_POSITION;
                    else if (index > 7 && index < 11 || index == 14)
                        position = SoccerPlayer.FORWARD_POSITION;
                    else
                        index = -1;
                }

                int cotization = getFantasyTeamCotization();

                List<SoccerPlayer> tempPlayers = new LinkedList<SoccerPlayer>( getView().getSoccerPlayers() );
                if ( soccerPlayer != null )
                    tempPlayers.remove( soccerPlayer );
                QueryAFAPlayersViewImpl queryPlayersView = new QueryAFAPlayersViewImpl( null, true, position, Constants.TOTAL_MONEY - cotization + (soccerPlayer==null? 0 : soccerPlayer.getPrice()), tempPlayers );
                QueryAFAPlayersPresenter queryPlayersPresenter = new QueryAFAPlayersPresenter( queryPlayersView );
                queryPlayersPresenter.getView().asWidget().setVisible( true );

                SoccerPlayer player = queryPlayersPresenter.getSelectedPlayer();

                if (player != null) {
                    getView().setPlayerAtPosition( index, player );
                    cotization = getFantasyTeamCotization();
                    getView().setLLevasGastado( cotization );
                    getView().setTeQuedan( Constants.TOTAL_MONEY - cotization );
                }
            }
        };
        getView().addQueryPlayersListener(queryPlayersListener);

        savePlayersListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String fantasyTeamName = getView().getFantasyTeamName();

                if (fantasyTeamName == null || fantasyTeamName.trim().isEmpty()) {
                    getView().showError( CreateFantasyTeamView.FANTASY_TEAM_NAME, "Por favor, ingrese el nombre del equipo.", "Error al salvar el equipo." );
                    return;
                }
                
                String name = getView().getFantasyTeamName();

                if ( rtservice.existRealTeamName( name ) ) {
                    getView().showError( CreateFantasyTeamView.FANTASY_TEAM_NAME, "<html>El nombre del equipo de fantasía debe ser distinto<br>al nombre de los equipos de primera división.<br>Por favor, elija otro nombre para su equipo.", "Error al salvar el equipo." );
                    return;
                }

                if ( ftservice.existFantasyTeamName( name ) ) {
                    getView().showError( CreateFantasyTeamView.FANTASY_TEAM_NAME, "<html>El nombre del equipo de fantasía coincide con el<br>nombre del equipo de fantasía de otro usuario.<br>Por favor, elija otro nombre para su equipo.", "Error al salvar el equipo." );
                    return;
                }

                List<SoccerPlayer> players = getView().getSoccerPlayers();

                if (players.size() != 15) {
                    getView().showError( CreateFantasyTeamView.FANTASY_TEAM_NAME, "Por favor, complete todas las pocisiones del equipo.", "Error al salvar el equipo." );
                    return;
                }

                FantasyTeam fantasyTeam = new FantasyTeam();

                int c = 0;
                List<FantasyTeamPlayer> ftps = new LinkedList<FantasyTeamPlayer>();
                for (SoccerPlayer player : players) {
                    FantasyTeamPlayer ftp = new FantasyTeamPlayer();
                    ftp.setBeginDate(new Date());
                    ftp.setFantasyTeam(fantasyTeam);
                    ftp.setRol(c++ < 11 ? FantasyTeamPlayer.TITULAR_ROLE : FantasyTeamPlayer.SUBSTITUTE_ROLE);
                    ftp.setSoccerPlayer(player);
                    ftps.add(ftp);
                }

                fantasyTeam.setName( fantasyTeamName );
                fantasyTeam.setFantasyTeamPlayerCollection( ftps );
                fantasyTeam.setTotalScore( 0 );
                fantasyTeam.setUser( (User) Tpdisenio2009App.loggedUser );
                fantasyTeam.setCreationDate( new Date() );

                ftservice.saveFantasyTeam(fantasyTeam);

                ((User) Tpdisenio2009App.loggedUser).setFantasyTeam( fantasyTeam );
                userService.update( (User) Tpdisenio2009App.loggedUser );

                getView().showNotification( "<html>¡Felicitaciones! Su equipo ha sido<br>creado correctamente.</html>", "Equipo creado" );
                getView().close();

            }
        };
        getView().addSaveListener(savePlayersListener);

        exitPlayersListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if( showConfirmation() ) {
                    Tpdisenio2009App.loggedUser = null;
                    System.exit(0);
                }
            }
        };
        getView().addExitListener(exitPlayersListener);
    }

    public void unbind() {
        if (queryPlayersListener != null) {
            getView().removeQueryPlayersListener(queryPlayersListener);
        }
        if (savePlayersListener != null) {
            getView().removeSaveListener(savePlayersListener);
        }
        if (exitPlayersListener != null) {
            getView().removeExitListener(exitPlayersListener);
        }
    }

    private boolean showConfirmation() {
        return getView().showConfirmation( "<html>¿Está seguro que desea salir?<br>Perderá la información no guardada de su equipo"  );
    }
}
